using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace Elementum
{
    public class Animation : Constant
    {
        protected Texture2D _texture;
        public Point _frameSize;
        protected Point _sheetSize;
        protected Point _currentFrame;
        protected bool _isTransform;
        protected Matrix _transform;
        protected Vector2 _position;
        Point _religionPos = new Point();

        protected int _deltaTime;
        protected int _frameTime;
        protected SpriteEffects _effect;

        List<Rectangle> _frameList=null;
        int _currentFrameCount = 0;
        //Rectangle _currentFrame;

        public SpriteEffects DrawEffect
        {
            get { return _effect; }
            set { _effect = value; }
        }

        public float LayerDepth { get; set; }

        public float Alpha { get; set; }

        public int CurrentFrameCount {
            get { return _currentFrameCount; }
            set
            {
                if (_frameList == null)
                    throw new Exception("null _frameList!!");
                if(value>=0&&value<_frameList.Count())
                    _currentFrameCount = value;
            }
        }

        public Color _animationColor;

        public Animation(Texture2D texture, Point frameSize)
        {
            this._texture = texture;
            this._frameSize = frameSize;
            this._sheetSize = new Point(texture.Width / frameSize.X, texture.Height / frameSize.Y);
            Initialize();
        }

        public Animation(string path, Point frameSize)
        {
            this._texture = ResourceManager.LoadTexture(path); ;
            this._frameSize = frameSize;
            this._sheetSize = new Point(_texture.Width / frameSize.X, _texture.Height / frameSize.Y);
            Initialize();
        }

        public Animation(string path, List<Rectangle> frameList)
        {
            this._texture = ResourceManager.LoadTexture(path);
            this._frameList = frameList;
            this._frameSize = new Point(frameList[0].Width,frameList[0].Height);
            this._sheetSize = new Point(_texture.Width / _frameSize.X, _texture.Height / _frameSize.Y);
            Initialize();
        }

        public Animation(string path, Rectangle religion, Point frameSize)
        {
            this._texture = ResourceManager.LoadTexture(path); ;
            this._frameSize = frameSize;
            this._sheetSize = new Point(religion.Width / frameSize.X, religion.Height / frameSize.Y);
            _religionPos.X = religion.X;
            _religionPos.Y = religion.Y;
            Initialize();
        }

        public Animation(string path)
        {
            this._texture = ResourceManager.LoadTexture(path); ;
            this._frameSize = new Point(_texture.Width, _texture.Height);
            this._sheetSize = new Point(_texture.Width / _frameSize.X, _texture.Height / _frameSize.Y);
            Initialize();
        }

        protected void Initialize()
        {
            _deltaTime = 50;
            _frameTime = 0;
            _currentFrame = new Point();
            Origin = new Vector2();
            Scale = 1f;
            Rotation = 0;
            Alpha = 1;
            IsReplay = true;
            DrawEffect = SpriteEffects.None;
            LayerDepth = 1;
            //_animationColor = new Color(255, 255, 255, 255) * Alpha;
        }

        public int DeltaTime
        {
            get
            {
                return _deltaTime;
            }
            set
            {
                _deltaTime = value;
            }
        }

        public float Rotation
        {
            get;
            set;
        }

        public void Reset()
        {
            _currentFrame.X = 0;
            _currentFrame.Y = 0;
        }

        public bool IsReplay
        {
            get;
            set;
        }

        public Vector2 Origin { get; set; }

        public float Scale { set; get; }

        public void OnDraw(SpriteBatch spriteBatch, Vector2 position, Matrix transform)
        {
            _isTransform = true;
            this._position = position;
            this._transform = transform;
            Vector2 drawPosition = _position;
            Rectangle source = new Rectangle(_religionPos.X + _currentFrame.X * _frameSize.X,
                                             _religionPos.Y + _currentFrame.Y * _frameSize.Y,
                                             _frameSize.X, _frameSize.Y);
            Vector2 bbg = new Vector2(source.Width / 2, source.Height / 2);
            _animationColor = new Color(255, 255, 255, 255) * Alpha;
            Origin = bbg;
            //spriteBatch.Begin(SpriteSortMode.FrontToBack, BlendState.AlphaBlend, null, null, null, null, transform);
            spriteBatch.Draw(_texture, drawPosition, source, _animationColor, -Rotation, Origin, Scale, DrawEffect, LayerDepth);
            //spriteBatch.End();

        }

        public void OnDraw(SpriteBatch spriteBatch, Vector2 position, Matrix transform, Rectangle drawArea)
        {
            _isTransform = true;
            this._position = position;
            this._transform = transform;
            Vector2 drawPosition = _position;
            //Rectangle source = new Rectangle(_currentFrame.X * _frameSize.X, _currentFrame.Y * _frameSize.Y, _frameSize.X, _frameSize.Y);
            Rectangle source;
            source = drawArea;
            Vector2 bbg = new Vector2(source.Width / 2, source.Height / 2);
            _animationColor = new Color(255, 255, 255, 255) * Alpha;
            Origin = bbg;
            //spriteBatch.Begin(SpriteSortMode.FrontToBack, BlendState.AlphaBlend, null, null, null, null, transform);
            spriteBatch.Draw(_texture, drawPosition, source, _animationColor, -Rotation, Origin, Scale, DrawEffect, LayerDepth);
            //spriteBatch.End();

        }

        public void OnDraw(SpriteBatch spriteBatch, Vector2 position)
        {
            this._position = position;
            _isTransform = false;
            
            _animationColor = new Color(255, 255, 255, 255) * Alpha;
            Rectangle source;
            source=  new Rectangle(_religionPos.X + _currentFrame.X * _frameSize.X, 
                              _religionPos.Y +_currentFrame.Y * _frameSize.Y, 
                              _frameSize.X, _frameSize.Y);
            Vector2 bbg = new Vector2(_frameSize.X / 2, _frameSize.Y / 2);
            Origin = bbg;

            spriteBatch.Draw(_texture, _position ,
             source , _animationColor ,- Rotation, Origin, Scale, DrawEffect, LayerDepth);
        }

        public Point FrameSize
        {
            get { return _frameSize; }
            private set { _frameSize = value; }
        }

        public bool IsInView(Vector2 point)
        {
            Vector2 posInScreen;
            if (_isTransform)
                posInScreen = Vector2.Transform(_position, _transform);
            else
                posInScreen = _position;

            Rectangle areaInScreen = new Rectangle((int)(posInScreen.X - _frameSize.X / 2),
                                        (int)(posInScreen.Y - _frameSize.Y / 2),
                                        _frameSize.X,
                                        _frameSize.Y);

            return areaInScreen.Contains(new Point((int)point.X, (int)point.Y));

        }

        public void Update(int delta)
        {
            _frameTime += delta;
            if (IsReplay && _frameTime > _deltaTime)
            {
                _frameTime -= _deltaTime;
                _currentFrame.X++;
                if (_currentFrame.X >= _sheetSize.X)//repeat
                {
                    _currentFrame.X = 0;
                    _currentFrame.Y++;
                    if (_currentFrame.Y >= _sheetSize.Y)//repeat
                        _currentFrame.Y = 0;
                }
            }
        }
    }
}
